﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using ZeldoEngineObjects.Maps;
using ZeldoEngineServices.Maps;
using ZeldoEngineObjects;

namespace ZeldoEngineDrawable.Maps
{
    public class MapDrawable
    {
        /// <summary>
        /// Texture de la map
        /// </summary>
        private Texture2D _chipset;
        private Texture2D[] _autotiles;
        //private SpriteFont _font;
        
        /// <summary>
        /// Charge les elements de la carte de jeu
        /// </summary>
        public void Charger(ContentManager content, Chipset chipset)
        {
            this._chipset = content.Load<Texture2D>(@"Chipset\" + chipset.NomFichier);
            this._autotiles = new Texture2D[EngineConsts.CHIPSET_AUTOTILES_NB];

            this._autotiles[0] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile1);
            this._autotiles[1] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile2);
            this._autotiles[2] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile3);
            this._autotiles[3] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile4);
            this._autotiles[4] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile5);
            this._autotiles[5] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile6);
            this._autotiles[6] = content.Load<Texture2D>(@"Autotiles\" + chipset.AutoTile7);

            //this._font = content.Load<SpriteFont>("SpriteFont");
        }

        /// <summary>
        /// Dessine à l'écran la carte de jeu
        /// </summary>
        public void Dessiner(SpriteBatch spriteBatch, MapModel map, MapModel.Layer layer, int offsetX, int offsetY, int tileSize, int chipsetWidth)
        {
            var unit = tileSize;
            var tileUnit = unit / 2;
            var chipWidth = chipsetWidth;

            for (var x = 0; x < map.Width; x++)
            {
                for (var y = 0; y < map.Height; y++)
                {
                    var nbMaxTilePerLine = chipWidth / unit;

                    var t = MapService.GetCompletTileInfos(map, layer, x, y);

                    if (t.HasValue)
                    {
                        var fullTile = t.Value;
                        var tuileIndex = (int)(fullTile & 0xFFFF);

                        if (tuileIndex > 0 && tuileIndex < nbMaxTilePerLine)
                        {
                            var codeTile = (fullTile >> 16) & 0xFFF;

                            var texture = this._autotiles[tuileIndex - 1];

                            var zRect = AutotileService.CalculerZones(codeTile, tileUnit);

                            var rectSourceA = new Rectangle(zRect[0].x, zRect[0].y, tileUnit, tileUnit);
                            var rectSourceB = new Rectangle(zRect[1].x, zRect[1].y, tileUnit, tileUnit);
                            var rectSourceC = new Rectangle(zRect[2].x, zRect[2].y, tileUnit, tileUnit);
                            var rectSourceD = new Rectangle(zRect[3].x, zRect[3].y, tileUnit, tileUnit);

                            var rectDestA = new Rectangle((x + offsetX) * unit, (y + offsetY) * unit, tileUnit, tileUnit);
                            var rectDestB = new Rectangle((x + offsetX) * unit + tileUnit, (y + offsetY) * unit, tileUnit, tileUnit);
                            var rectDestC = new Rectangle((x + offsetX) * unit, (y + offsetY) * unit + tileUnit, tileUnit, tileUnit);
                            var rectDestD = new Rectangle((x + offsetX) * unit + tileUnit, (y + offsetY) * unit + tileUnit, tileUnit, tileUnit);

                            spriteBatch.Draw(texture, rectDestA, rectSourceA, Color.White);
                            spriteBatch.Draw(texture, rectDestB, rectSourceB, Color.White);
                            spriteBatch.Draw(texture, rectDestC, rectSourceC, Color.White);
                            spriteBatch.Draw(texture, rectDestD, rectSourceD, Color.White);

                            //spriteBatch.DrawString(this.font, "" + ((fullTile >> 16) & 0x7), new Vector2(((x + offsetX) * unit) + 2, ((y + offsetY) * unit) + 1), Color.Red, 0, new Vector2(0, 0), 0.5f, SpriteEffects.None, 0.5f);
                            //spriteBatch.DrawString(this.font, "" + ((fullTile >> 19) & 0x7), new Vector2(((x + offsetX) * unit) + 20, ((y + offsetY) * unit) + 1), Color.Red, 0, new Vector2(0, 0), 0.5f, SpriteEffects.None, 0.5f);
                            //spriteBatch.DrawString(this.font, "" + ((fullTile >> 22) & 0x7), new Vector2(((x + offsetX) * unit) + 2, ((y + offsetY) * unit) + 20), Color.Red, 0, new Vector2(0, 0), 0.5f, SpriteEffects.None, 0.5f);
                            //spriteBatch.DrawString(this.font, "" + ((fullTile >> 25) & 0x7), new Vector2(((x + offsetX) * unit) + 20, ((y + offsetY) * unit) + 20), Color.Red, 0, new Vector2(0, 0), 0.5f, SpriteEffects.None, 0.5f);
                        }
                        else if (tuileIndex >= nbMaxTilePerLine)
                        {
                            tuileIndex -= nbMaxTilePerLine;
                            int targetLine = tuileIndex / nbMaxTilePerLine;
                            var rectSource = new Rectangle((tuileIndex - (targetLine * nbMaxTilePerLine)) * unit, targetLine * unit, unit, unit);
                            var rectDest = new Rectangle((x + offsetX) * unit, (y + offsetY) * unit, unit, unit);

                            spriteBatch.Draw(this._chipset, rectDest, rectSource, Color.White);
                        }
                    }
                }
            }
        }
    }
}
